奥维地图 | 新版本坐标无偏移导出插件制作与分享!
(本文系测绘营地原创 | 全文约2200字)
在9.3.0及以后版本的奥维地图中,取消wgs84坐标的kml/kmz导出,改成gcj02坐标的ovkml/ovkmz导出,而且对于txt、csv格式的导出也施加了gcj02坐标偏移。
虽然对于dxf、shp等格式,新版本奥维仍然是无偏移导出的,但对于经常使用kml、txt、csv等格式的用户,新版本奥维带来的偏移量往往是无法接受的。
解决这个问题的办法很多,比如从新版本中导出ovobj文件,导入旧版本软件再导出kml;或者从新版本中导出dxf格式,利用Global Mapper、Arcgis或其它GIS软件将dxf转换成kml格式。
但对于大多数轻度或测绘行业外的用户来说,好像也不太方便:
新旧版本经常搞混
不会用Global Mapper、Arcgis这些专业软件
dxf转kml的时候投影参数设置错误
忘记新版本有偏移,办公室导出的数据到现场才发现对不上
为了解决这一问题,我利用奥维地图在9.3.8版本新增的“导出对象时支持第三方格式转换插件”这一功能,上网查询了相关坐标转换算法,编写了一个坐标转换插件,免费分享给大家使用。
为了对比新版本的偏移量,这里使用的是无偏的9.0.3版本与带偏移的9.3.8版本。
在全国34个省级行政区域分别设置了一个标签点,分别利用9.0.3版本与9.3.8版本导出txt格式的坐标文件。
(底图为高德卫星影像地图,审图号:GS(2022)1083号)
在Excel中,将新版本与旧版本导出的坐标进行差值计算,再利用差值经纬度换算出实地的偏移量。
地球的子午线总长度大约40008km,因此纬度差1度对应的实际距离约为40008/360≈111.13千米;经度差1度对应的实际距离约为111.13千米*cos(纬度)。
可以看出,除了香港和台湾两个点位没有偏移外,其余点位出现了数百米的偏移量。
在奥维互动地图官网(https://www.ovital.com/140208-2/),可以直接下载官方给出的格式转换示例插件,格式为ovocj,可直接用记事本打开。
示例插件中的声明信息如下:
<!--示例插件声明:此插件仅供用户在二次开发时参考使用,我们不会对示例代码的可靠性和完整性作任何保障,有需要的用户可以根据此示例进行二次开发和完善。-->
<!--本示例简单演示了如何在导出对象时,根据输入参数,修改对象经纬度数据。-->
该示例插件仅仅提供了一个框架,而不包含实际的坐标转换代码,而有的文章直接就将这个空空如也的示例分享了出来,有的则只能转换标签点数据、而无法转换线数据和面数据。
新版本奥维导出数据为GCJ02坐标,所以转换的核心思路就是将GCJ02坐标转换为WGS84坐标即可。
其实六月底我就已经做出了现在这个版本的插件,但无法做到100%完全无偏的转换。
后来通过大量的搜索、尝试和验证,发现网上公开的坐标转换代码均为通过大量数据近似推导的纠偏算法,而非精确的解密算法。
要想实现精确的纠偏转换,则需要利用一些动态的代码库来实现(能够真正实现还不得而知),而奥维这种简单的二次开发显然不支持这种开发模式。
毕竟,从WGS84到GCJ02的转换是非线性的,在未知官方转换参数的前提下,只能通过大量的坐标数据进行“反推”,从而推导出一个近似的GCJ02到WGS84的反向转换公式,而这个过程必然会产生一定的精度损失。
因此,本次分享的转换插件也是一种近似转换,转换精度为米级。
插件主要代码如下:
▼纬度坐标转换
function changeLat(gcjlng, gcjlat){
var dlat = transformlat(gcjlng - 105.0, gcjlat - 35.0);
var dlng = transformlng(gcjlng - 105.0, gcjlat - 35.0);
var radlat = gcjlat / 180.0 * pi;
var magic = Math.sin(radlat);
magic = 1 - ee * magic * magic;
var sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);
return dlat;
}
▼经度坐标转换
function changeLng(gcjlng, gcjlat){
var dlat = transformlat(gcjlng - 105.0, gcjlat - 35.0);
var dlng = transformlng(gcjlng - 105.0, gcjlat - 35.0) ;
var radlat = gcjlat / 180.0 * pi;
var magic = Math.sin(radlat);
magic = 1 - ee * magic * magic;
var sqrtmagic = Math.sqrt(magic);
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);
return dlng;
}
▼转换标签点数据
case OMAP_OBJ_TYPE_SIGN:
Detail.Lat = Detail.Lat - changeLat(Detail.Lng, Detail.Lat); //alert(Detail.Lat)
Detail.Lng = Detail.Lng - changeLng(Detail.Lng, Detail.Lat);
break;
▼转换轨迹线数据
case OMAP_OBJ_TYPE_TRACK:
latlng = Detail.Latlng;
var size = latlng.length;
for (var i = 0; i < size; i += 2) {
latlng[i] = latlng[i] - changeLat(latlng[i + 1], latlng[i]) ;
latlng[i + 1] = latlng[i + 1] - changeLng(latlng[i + 1], latlng[i]);
}
Detail.latlng = latlng;
break;
▼转换范围面数据
case OMAP_OBJ_TYPE_SHAPE:
latlng = Detail.Latlng;
var size = latlng.length;
for (var i = 0; i < size; i += 2) {
latlng[i] = latlng[i] - changeLat(latlng[i + 1], latlng[i]) ;
latlng[i + 1] = latlng[i + 1] - changeLng(latlng[i + 1], latlng[i]);
}
Detail.latlng = latlng;
break;
利用最新9.3.8版本奥维软件,使用我做好的格式转换插件进行txt数据导出,与9.0.3版本导出数据的坐标差值如下:
根据n个点的坐标转换精度估计公式:
可计算出对于选取的除香港、台湾以外的32个标签点数据,格式转换插件的转换点位中误差约为1.51米。
1、选择需要导出的对象(单选多选都可以),右键-选择【导出】。
2、在【格式】中选择ovkml、ovkmz、txt、csv其中一种,在【插件】右方选择【管理】,点击导入,选择公众号分享给大家的【无偏坐标导出插件(2米精度).ovocp】文件导入。
3、在【插件】栏选择刚刚导入的插件,选择【导出】即可,导出完成后会弹出导出成功的提示。
需要的读者可直接在文章末尾,点击“发消息”,在公众号后台回复关键词【奥维插件】获取下载链接。
(点击图片可查看文章👇)
每一篇原创,都是干货